/**
 * Copyright (c) 2018 九色 All rights reserved.
 *
 * https://www.chenglicun.io
 *
 * 版权所有，侵权必究！
 */

package io.chenglicun.modules.sys.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.chenglicun.common.entity.BaseEntity;
import io.chenglicun.common.page.PageData;
import io.chenglicun.common.service.impl.BaseServiceImpl;
import io.chenglicun.common.utils.ConvertUtils;
import io.chenglicun.modules.clc.dto.ClcUserDeptDTO;
import io.chenglicun.modules.clc.dto.ClcUserIdentityDTO;
import io.chenglicun.modules.clc.service.ClcUserDeptService;
import io.chenglicun.modules.clc.service.ClcUserIdentityService;
import io.chenglicun.modules.security.password.PasswordUtils;
import io.chenglicun.modules.security.user.SecurityUser;
import io.chenglicun.common.user.UserDetail;
import io.chenglicun.modules.sys.dao.SysUserDao;
import io.chenglicun.modules.sys.dto.SysUserDTO;
import io.chenglicun.modules.sys.entity.SysUserEntity;
import io.chenglicun.modules.sys.enums.SuperAdminEnum;
import io.chenglicun.modules.sys.service.SysDeptService;
import io.chenglicun.modules.sys.service.SysRoleUserService;
import io.chenglicun.modules.sys.service.SysUserPostService;
import io.chenglicun.modules.sys.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 系统用户
 * 
 * @author Mark sunlightcs@gmail.com
 */
@Service
public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
	@Autowired
	private SysRoleUserService sysRoleUserService;
	@Autowired
	private SysDeptService sysDeptService;
	@Autowired
	private SysUserPostService sysUserPostService;
	@Autowired
	private ClcUserIdentityService userIdentityService;
	@Autowired
	private ClcUserDeptService userDeptService;

	@Override
	public PageData<SysUserDTO> page(Map<String, Object> params) {
		//转换成like
		paramsToLike(params, "username");

		//分页
		IPage<SysUserEntity> page = getPage(params, "t1.create_date", false);

		Long deptId = ObjectUtil.isEmpty(params.get("deptId")) ? null : Long.parseLong(params.get("deptId").toString());


		//普通管理员，只能查询所属部门及子部门的数据
		UserDetail user = SecurityUser.getUser();
		if (deptId != null) {
			params.put("deptIdList", sysDeptService.getSubDeptIdList(deptId));
		} else
		if(user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
			params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId()));
		}

		//查询
		List<SysUserEntity> list = baseDao.getList(params);

		PageData<SysUserDTO> pageData = getPageData(list, page.getTotal(), SysUserDTO.class);
		this.setData(pageData.getList());
		return pageData;
	}

	@Override
	public List<SysUserDTO> list(Map<String, Object> params) {
		//普通管理员，只能查询所属部门及子部门的数据
		UserDetail user = SecurityUser.getUser();
		if(user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
			params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId()));
		}

		List<SysUserEntity> entityList = baseDao.getList(params);

		List<SysUserDTO> dtos = ConvertUtils.sourceToTarget(entityList, SysUserDTO.class);
		this.setData(dtos);
		return dtos;
	}

	@Override
	public SysUserDTO get(Long id) {
		SysUserEntity entity = baseDao.getById(id);

		SysUserDTO dto = ConvertUtils.sourceToTarget(entity, SysUserDTO.class);
		this.setData(dto);
		return dto;
	}

	@Override
	public SysUserDTO getByUsername(String username) {
		SysUserEntity entity = baseDao.getByUsername(username);

		SysUserDTO dto = ConvertUtils.sourceToTarget(entity, SysUserDTO.class);
		this.setData(dto);
		return dto;
	}

	private void setData(List<SysUserDTO> list) {
		if (list.size() == 0) return;
		Long[] userIds = list.stream().map(SysUserDTO::getId).toArray(Long[]::new);
		List<ClcUserIdentityDTO> userIdentityDTOS = userIdentityService.getByUserIds(userIds);

		List<ClcUserDeptDTO> userDeptList = userDeptService.getByUserIds(userIds);
		for (SysUserDTO dto : list) {
			List<ClcUserIdentityDTO> collect = userIdentityDTOS.stream().filter(t -> t.getUserId().equals(dto.getId())).collect(Collectors.toList());
			dto.setIdentityList(collect);

			List<ClcUserDeptDTO> collect1 = userDeptList.stream().filter(t -> t.getUserId().equals(dto.getId())).collect(Collectors.toList());
			dto.setDeptList(collect1);
		}
	}

	private void setData(SysUserDTO dto) {
		if (dto == null) return;
		List<ClcUserIdentityDTO> userIdentityDTOS = userIdentityService.getByUserIds(dto.getId());
		dto.setIdentityList(userIdentityDTOS);

		List<ClcUserDeptDTO> userDeptList = userDeptService.getByUserIds(dto.getId());
		dto.setDeptList(userDeptList);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void save(SysUserDTO dto) {
		SysUserEntity entity = ConvertUtils.sourceToTarget(dto, SysUserEntity.class);

		//密码加密
		String password = PasswordUtils.encode(entity.getPassword());
		entity.setPassword(password);

		//保存用户
		entity.setSuperAdmin(SuperAdminEnum.NO.value());
		insert(entity);

		//保存用户部门关系
		userDeptService.saveOrUpdate(entity.getId(), dto.getDeptList());

		//保存角色用户关系
		sysRoleUserService.saveOrUpdate(entity.getId(), dto.getRoleIdList());

		//保存用户岗位关系
		sysUserPostService.saveOrUpdate(entity.getId(), dto.getPostIdList());

		//保存用户身份关系
		userIdentityService.saveOrUpdate(entity.getId(), dto.getIdentityIdList());
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void update(SysUserDTO dto) {
		SysUserEntity entity = ConvertUtils.sourceToTarget(dto, SysUserEntity.class);

		//密码加密
		if(StringUtils.isBlank(dto.getPassword())){
			entity.setPassword(null);
		}else{
			String password = PasswordUtils.encode(entity.getPassword());
			entity.setPassword(password);
		}

		//更新用户
		updateById(entity);

		//更新用户部门关系
		userDeptService.saveOrUpdate(entity.getId(), dto.getDeptList());

		//更新角色用户关系
		sysRoleUserService.saveOrUpdate(entity.getId(), dto.getRoleIdList());

		//保存用户岗位关系
		sysUserPostService.saveOrUpdate(entity.getId(), dto.getPostIdList());

		//保存用户身份关系
		userIdentityService.saveOrUpdate(entity.getId(), dto.getIdentityIdList());
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateUserInfo(SysUserDTO dto) {
		SysUserEntity entity = selectById(dto.getId());
		entity.setHeadUrl(dto.getHeadUrl());
		entity.setRealName(dto.getRealName());
		entity.setGender(dto.getGender());
		entity.setMobile(dto.getMobile());
		entity.setEmail(dto.getEmail());

		updateById(entity);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delete(Long[] ids) {
		//删除用户
		baseDao.deleteBatchIds(Arrays.asList(ids));

		//删除用户部门关系
		userDeptService.deleteByUserIds(ids);

		//删除角色用户关系
		sysRoleUserService.deleteByUserIds(ids);

		//删除用户岗位关系
		sysUserPostService.deleteByUserIds(ids);

		//删除用户身份关系
		userIdentityService.deleteByUserIds(ids);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updatePassword(Long id, String newPassword) {
		newPassword = PasswordUtils.encode(newPassword);

		baseDao.updatePassword(id, newPassword);
	}

	@Override
	public int getCountByDeptId(Long deptId) {
		return baseDao.getCountByDeptId(deptId);
	}

	@Override
	public List<Long> getUserIdListByDeptId(List<Long> deptIdList) {
		return baseDao.getUserIdListByDeptId(deptIdList);
	}

}
